package com.ctv.my.customview.BaiajCustomView.View;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;

import com.ctv.my.customview.R;

/**
 * Created by baiaj on 2017/8/15.
 */

public class ThridBezier extends ViewGroup implements Animator.AnimatorListener {

    // 神奇的数字,数据点和控制点之间的比例(数据点X * C = 控制点X)
    private static final float MAGIC_NUMBER_C = 0.552284749831f;
    // 默认颜色
    private static final String COLOR1 = "#B04285F4";
    private static final String COLOR2 = "#B0EA4335";
    private static final String COLOR3 = "#B0FBBC05";
    private static final String COLOR4 = "#B034A853";

    private int mWidth, mHeight;
    // 开始位置
    private int startX, startY;
    // 当前位置
    private int currentX, currentY;
    private float mCicleRadius;
    private float moveAvg;
    private float distance;

    // 需要移动的距离
    private float moveDis;
    // 动画时长
    private int moveDuation;
    // 4个数据点移动的距离
    private float move1 = 0;
    private float move2 = 0;
    private float move3 = 0;
    private float move4 = 0;
    // 位移次数
    private int moveCount;
    // 位移冗余距离
    private float moveRedun;
    // 状态
    private int status = 0;
    // 顺时针记录绘制圆形的四个数据点
    private float[] mData = new float[8];
    // 顺时针记录绘制圆形的八个控制点
    private float[] mControl = new float[16];

    private Paint mPaint;
    private Paint mClickPaint;
    private Paint mCirclePaint;
    // 子View个数
    private int tabNum;
    // 圆之间的距离
    private int div;
    // 4个button的颜色
    private int[] colors = new int[4];
    // 点击button动画的颜色
    private int clickColor;
    // 圆在中间的颜色
    private int circleColor;
    // 方向 0:左 1:右
    private int direction;
    // 当前颜色
    private int colorIndex = 0;
    // 点击动画
    private ValueAnimator animationClick;
    // 当前动画的值
    private int animValue = 0;
    // Viewpager
    private ViewPager mViewPager;

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            status++;
            if (status == 1) {
                if (direction == 1) {
                    move3 = move3 + moveAvg;
                } else {
                    move1 = move1 - moveAvg;
                }
            } else if (status == 2) {
                if (direction == 1) {
                    move2 = move2 + moveAvg;
                    move3 = move3 + moveAvg;
                    move4 = move4 + moveAvg;
                } else {
                    move2 = move2 - moveAvg;
                    move1 = move1 - moveAvg;
                    move4 = move4 - moveAvg;
                }
            } else if (status > 2 && status <= moveCount) {
                float distance = moveAvg;
                if (status == moveCount) {
                    if (moveRedun != 0) {
                        distance = distance + moveRedun;
                    }
                }
                distance = direction == 1 ? distance : -distance;
                move1 = move1 + distance;
                move2 = move2 + distance;
                move3 = move3 + distance;
                move4 = move4 + distance;
            } else if (status == moveCount + 1) {
                if (direction == 1) {
                    move1 = move1 + moveAvg;
                    move2 = move2 + moveAvg;
                    move4 = move4 + moveAvg;
                } else {
                    move3 = move3 - moveAvg;
                    move2 = move2 - moveAvg;
                    move4 = move4 - moveAvg;
                }
            } else if (status == moveCount + 2) {
                if (direction == 1) {
                    move1 = move1 + moveAvg;
                } else {
                    move3 = move3 - moveAvg;
                }
            }
            notifyData();
            invalidate();
        }
    };

    public ThridBezier(Context context) {
        this(context, null);
    }

    public ThridBezier(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ThridBezier(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.thirdbezierCicle);
        colors[0] = typedArray.getColor(R.styleable.thirdbezierCicle_color1, Color.parseColor(COLOR1));
        colors[1] = typedArray.getColor(R.styleable.thirdbezierCicle_color2, Color.parseColor(COLOR2));
        colors[2] = typedArray.getColor(R.styleable.thirdbezierCicle_color3, Color.parseColor(COLOR3));
        colors[3] = typedArray.getColor(R.styleable.thirdbezierCicle_color4, Color.parseColor(COLOR4));
        circleColor = typedArray.getColor(R.styleable.thirdbezierCicle_circle_color, Color.GRAY);
        clickColor = typedArray.getColor(R.styleable.thirdbezierCicle_click_color, Color.WHITE);
        mCicleRadius = typedArray.getDimension(R.styleable.thirdbezierCicle_radiu, 50);
        moveDuation = typedArray.getInteger(R.styleable.thirdbezierCicle_duration, 1000);
        moveAvg = mCicleRadius / 2;
        distance = mCicleRadius * MAGIC_NUMBER_C;
        initPaint();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int sizeWidth = MeasureSpec.getSize(widthMeasureSpec);
        int sizeHeight = MeasureSpec.getSize(heightMeasureSpec);
        tabNum = getChildCount();
        for (int i = 0; i < tabNum; i++) {
            View child = getChildAt(i);
            // 让子View自己测量大小
            measureChild(child, widthMeasureSpec, heightMeasureSpec);
        }
        // 设置ViewGroup的大小
        setMeasuredDimension(sizeWidth, sizeHeight);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        tabNum = getChildCount();
        for (int i = 0; i < tabNum; i++) {
            View child = getChildAt(i);
            // 确定子View在ViewGroup中的位置
            child.layout((int) (div * (i + 1) + mCicleRadius * 2 * i + mCicleRadius * 0.5), (int) (startY - mCicleRadius * 0.5),
                    (int) (div * (i + 1) + mCicleRadius * 2 * (i + 1) - mCicleRadius * 0.5), (int) (startY + mCicleRadius * 0.5));
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
        div = (int) ((w - 2 * tabNum * mCicleRadius) / (tabNum + 1));
        startX = (int) (div + mCicleRadius);
        startY = h / 2;
        currentX = startX;
        currentY = startY;
        notifyData();
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        tabNum = getChildCount();
        for (int i = 0; i < tabNum; i++) {
            canvas.drawCircle(div * (i + 1) + (i * 2 + 1) * mCicleRadius, startY, mCicleRadius - 5, mCirclePaint);
        }
        Path path = new Path();
        path.moveTo(mData[0], mData[1]);
        path.cubicTo(mControl[0], mControl[1], mControl[2], mControl[3], mData[2], mData[3]);
        path.cubicTo(mControl[4], mControl[5], mControl[6], mControl[7], mData[4], mData[5]);
        path.cubicTo(mControl[8], mControl[9], mControl[10], mControl[11], mData[6], mData[7]);
        path.cubicTo(mControl[12], mControl[13], mControl[14], mControl[15], mData[0], mData[1]);
        if (status == 0) {
            canvas.drawCircle(currentX, startY, mCicleRadius / animValue, mClickPaint);
        }
        // 根据当前状态选择画笔颜色
        if (status > 1 && status < moveCount + 2) {
            mPaint.setColor(circleColor);
        } else if (status == moveCount + 2) {
            mPaint.setColor(colors[colorIndex]);
        }
        canvas.drawPath(path, mPaint);
        if (status == moveCount + 2) {
            status = 0;
            mViewPager.setCurrentItem(colorIndex);
        } else if (status > 0 && status < moveCount + 2) {
            mHandler.sendEmptyMessageDelayed(0, moveDuation / moveCount);
        }
        super.dispatchDraw(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // 根据点击位置确定位移方向和距离
        if (status == 0) {
            float x = event.getX();
            if (x < currentX - mCicleRadius || x > currentX + mCicleRadius) {
                if (x >= div && x <= div + mCicleRadius * 2) {
                    moveDis = Math.abs(currentX - (div + mCicleRadius));
                    moveCount = (int) (moveDis / moveAvg);
                    moveRedun = moveDis - moveCount * moveAvg;
                    colorIndex = 0;
                    direction = x - currentX > 0 ? 1 : 0;
                    currentX = (int) (div + mCicleRadius);
                    startClickAnim();
                } else if (x >= 2 * div + 2 * mCicleRadius && x <= 2 * div + 4 * mCicleRadius) {
                    moveDis = Math.abs(currentX - (2 * div + 3 * mCicleRadius));
                    moveCount = (int) (moveDis / moveAvg);
                    moveRedun = moveDis - moveCount * moveAvg;
                    colorIndex = 1;
                    direction = x - currentX > 0 ? 1 : 0;
                    currentX = (int) (2 * div + 3 * mCicleRadius);
                    startClickAnim();
                } else if (x >= 3 * div + 4 * mCicleRadius && x <= 3 * div + 6 * mCicleRadius) {
                    moveDis = Math.abs(currentX - (3 * div + 5 * mCicleRadius));
                    moveCount = (int) (moveDis / moveAvg);
                    moveRedun = moveDis - moveCount * moveAvg;
                    colorIndex = 2;
                    direction = x - currentX > 0 ? 1 : 0;
                    currentX = (int) (3 * div + 5 * mCicleRadius);
                    startClickAnim();
                } else if (x >= 4 * div + 6 * mCicleRadius && x <= 4 * div + 8 * mCicleRadius) {
                    moveDis = Math.abs(currentX - (4 * div + 7 * mCicleRadius));
                    moveCount = (int) (moveDis / moveAvg);
                    moveRedun = moveDis - moveCount * moveAvg;
                    colorIndex = 3;
                    direction = x - currentX > 0 ? 1 : 0;
                    currentX = (int) (4 * div + 7 * mCicleRadius);
                    startClickAnim();
                }
            }
        }
        return super.onTouchEvent(event);
    }

    private void initPaint() {
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mPaint.setColor(colors[0]);
        mPaint.setAntiAlias(true);

        mCirclePaint = new Paint();
        mCirclePaint.setStyle(Paint.Style.STROKE);
        mCirclePaint.setStrokeWidth(2);
        mCirclePaint.setColor(Color.WHITE);
        mCirclePaint.setAntiAlias(true);

        mClickPaint = new Paint();
        mClickPaint.setStyle(Paint.Style.FILL);
        mClickPaint.setColor(clickColor);
        mClickPaint.setAntiAlias(true);
    }

    /* 初始化基本数据 */
    private void notifyData() {
        // 初始化数据点
        mData[0] = startX - mCicleRadius + move1;
        mData[1] = startY;

        mData[2] = startX + move2;
        mData[3] = startY - mCicleRadius;

        mData[4] = startX + mCicleRadius + move3;
        mData[5] = startY;

        mData[6] = startX + move4;
        mData[7] = startY + mCicleRadius;
        // 初始化控制点
        mControl[0] = mData[0];
        mControl[1] = mData[1] - distance;

        mControl[2] = mData[2] - distance;
        mControl[3] = mData[3];

        mControl[4] = mData[2] + distance;
        mControl[5] = mData[3];

        mControl[6] = mData[4];
        mControl[7] = mData[5] - distance;

        mControl[8] = mData[4];
        mControl[9] = mData[5] + distance;

        mControl[10] = mData[6] + distance;
        mControl[11] = mData[7];

        mControl[12] = mData[6] - distance;
        mControl[13] = mData[7];

        mControl[14] = mData[0];
        mControl[15] = mData[1] + distance;
    }

    // 开始点击动画
    private void startClickAnim() {
        animationClick = ValueAnimator.ofInt(10, 0);
        animationClick.setDuration(250);
        animationClick.addListener(this);
        animationClick.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                animValue = (int) valueAnimator.getAnimatedValue();
                invalidate();
            }
        });
        animationClick.start();
    }

    // 设置ViewPager
    public void setViewPager(ViewPager viewpager){
        mViewPager = viewpager;
        viewpager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                float x = div + mCicleRadius + (position * (div + 2 * mCicleRadius));
                moveDis = Math.abs(currentX - x);
                if (moveDis != 0){
                    moveCount = (int) (moveDis / moveAvg);
                    moveRedun = moveDis - moveCount * moveAvg;
                    colorIndex = position;
                    direction = x - currentX > 0 ? 1 : 0;
                    currentX = (int) x;
                    mHandler.sendEmptyMessageDelayed(0,moveDuation / moveCount);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }

    @Override
    public void onAnimationStart(Animator animator) {
    }

    @Override
    public void onAnimationEnd(Animator animator) {
        mHandler.sendEmptyMessageDelayed(0, moveDuation / moveCount);
    }

    @Override
    public void onAnimationCancel(Animator animator) {
    }

    @Override
    public void onAnimationRepeat(Animator animator) {
    }
}